package com.pine.dcts.task;

import com.pine.dcts.common.TaskStatusType;
import com.pine.dcts.config.DctsPropertis;
import com.pine.dcts.service.TaskRunnerCallback;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author xiaoyuan
 * @create 2021/6/2 17:05
 **/
@Slf4j
public class DefaultTaskStatCollector implements TaskStatCollector {

    /**
     * 浮点数极小误差值，浮点数运算有误差，绝对值小于这个数可以当成0
     */
    private static final double EPS = 1E-6;

    private static final Map<String, TaskExecutorStat> TASK_CONTAINER_MAP = new ConcurrentHashMap();

    private DctsPropertis dctsPropertis;

    @Override
    public synchronized boolean pushTask(TaskExecutorStat executorStat) {
        if (TASK_CONTAINER_MAP.containsKey(executorStat.getTaskMeta().getTaskId())) {
            log.debug("任务【id:{},name:{}】已开始运行，请勿重复创建", executorStat.getTaskMeta().getTaskId(), executorStat.getTaskMeta().getTaskName());
            callback(executorStat.getCallback(), TaskStatusType.NOT_START, "任务已存在");
            return false;
        }
        if (taskSize() > dctsPropertis.getTask().getMaxNum()) {
            callback(executorStat.getCallback(), TaskStatusType.NOT_START, "任务池已达到最大量");
            return false;
        }
        TASK_CONTAINER_MAP.put(executorStat.getTaskMeta().getTaskId(), executorStat);
        return true;
    }

    @Override
    public boolean remove(String taskId) {
        TASK_CONTAINER_MAP.remove(taskId);
        return true;
    }

    @Override
    public TaskExecutorStat get(String taskId) {
        return TASK_CONTAINER_MAP.get(taskId);
    }

    @Override
    public Collection<TaskExecutorStat> getAll() {
        return TASK_CONTAINER_MAP.values();
    }

    @Override
    public boolean containsKey(String taskId) {
        return TASK_CONTAINER_MAP.containsKey(taskId);
    }

    @Override
    public int taskSize() {
        return TASK_CONTAINER_MAP.size();
    }

    @Override
    public void clear() {
        TASK_CONTAINER_MAP.clear();
    }

    private void callback(TaskRunnerCallback callback, TaskStatusType statusType, String message) {
        callback.setTaskStatus(statusType);
        callback.setMessage(message);
        callback.callback();
    }
}
